// ==UserScript==
// @name         MP4 to GIF Converter
// @namespace    http://tampermonkey.net/
// @version      0.3
// @description  将网页视频转换为GIF（支持跨域视频）
// @author       You
// @match        *://*/*
// @grant        GM_addStyle
// @grant        GM_xmlhttpRequest
// @connect      *
// @require      https://cdnjs.cloudflare.com/ajax/libs/gif.js/0.2.0/gif.js
// ==/UserScript==

(function() {
    'use strict';

    // 省略之前的CSS样式...
    GM_addStyle(`
        /* 前面的样式保持不变 */
        .video-item {
            padding: 10px;
            border-bottom: 1px solid #eee;
            cursor: pointer;
            display: flex;
            align-items: center;
            gap: 10px;
        }

        .video-item:hover {
            background: #f5f5f5;
        }

        .video-item.selected {
            background: #e3f2fd;
        }

        .video-source {
            font-size: 12px;
            color: #666;
            word-break: break-all;
            max-width: 300px;
            overflow: hidden;
            text-overflow: ellipsis;
        }

        .error-message {
            color: #f44336;
            font-size: 12px;
            margin-top: 5px;
        }
    `);

    // 创建转换器界面
    const converterHTML = `
        <div class="gif-converter-widget">
            <button class="gif-converter-toggle">MP4转GIF工具</button>
            <div class="gif-converter-panel">
                <h2>MP4转GIF工具</h2>
                
                <div id="videoList" class="video-list">
                    <div class="status">正在扫描页面视频...</div>
                </div>

                <div class="settings">
                    <div class="setting-item">
                        <label>
                            质量 <span id="gifConverterQualityValue" class="value-display">10</span>
                            <input type="range" id="gifConverterQuality" min="1" max="30" value="10" />
                        </label>
                    </div>

                    <div class="setting-item">
                        <label>
                            帧率 (FPS) <span id="gifConverterFpsValue" class="value-display">15</span>
                            <input type="range" id="gifConverterFps" min="1" max="30" value="15" />
                        </label>
                    </div>

                    <div class="setting-item">
                        <label>
                            最大帧数
                            <input type="number" id="gifConverterMaxFrames" value="100" min="1" max="300" />
                        </label>
                    </div>

                    <div class="setting-item">
                        <label>
                            输出宽度
                            <input type="number" id="gifConverterWidth" placeholder="原始宽度" />
                        </label>
                    </div>
                </div>

                <button id="gifConverterConvertBtn" disabled>开始转换</button>

                <div class="progress-container">
                    <div class="progress-bar">
                        <div class="progress"></div>
                    </div>
                    <div class="status">准备转换...</div>
                </div>
            </div>
        </div>
    `;

    // 添加界面到页面
    document.body.insertAdjacentHTML('beforeend', converterHTML);

    let selectedVideoUrl = null;
    let selectedVideoElement = null;

    // 获取视频真实URL
    function getVideoUrl(video) {
        const sourceEl = video.querySelector('source');
        return video.src || sourceEl?.src || video.currentSrc;
    }

    // 使用GM_xmlhttpRequest获取视频数据
    function fetchVideo(url) {
        return new Promise((resolve, reject) => {
            GM_xmlhttpRequest({
                method: 'GET',
                url: url,
                responseType: 'blob',
                onload: function(response) {
                    resolve(response.response);
                },
                onerror: function(error) {
                    reject(error);
                }
            });
        });
    }

    // 创建视频项
    function createVideoItem(video, index) {
        const videoUrl = getVideoUrl(video);
        if (!videoUrl) return null;

        const videoItem = document.createElement('div');
        videoItem.className = 'video-item';
        videoItem.innerHTML = `
            <div class="video-item-details">
                <div>视频 ${index + 1}</div>
                <div class="video-source">${videoUrl}</div>
            </div>
        `;

        videoItem.addEventListener('click', async () => {
            document.querySelectorAll('.video-item').forEach(item => {
                item.classList.remove('selected');
            });
            videoItem.classList.add('selected');
            
            selectedVideoUrl = videoUrl;
            selectedVideoElement = video;
            convertBtn.disabled = false;
        });

        return videoItem;
    }

    // 更新视频列表
    function updateVideoList() {
        const videos = document.querySelectorAll('video');
        videoList.innerHTML = '';

        if (videos.length === 0) {
            videoList.innerHTML = '<div class="status">未找到视频</div>';
            return;
        }

        videos.forEach((video, index) => {
            const videoItem = createVideoItem(video, index);
            if (videoItem) {
                videoList.appendChild(videoItem);
            }
        });
    }

    // 转换视频为GIF
    async function convertToGif(videoElement, videoUrl) {
        const canvas = document.createElement('canvas');
        const ctx = canvas.getContext('2d');
        
        // 创建一个新的视频元素用于转换
        const tempVideo = document.createElement('video');
        tempVideo.crossOrigin = 'anonymous';
        
        try {
            // 获取视频blob数据
            const videoBlob = await fetchVideo(videoUrl);
            const blobUrl = URL.createObjectURL(videoBlob);
            
            // 加载视频
            await new Promise((resolve, reject) => {
                tempVideo.onloadedmetadata = resolve;
                tempVideo.onerror = reject;
                tempVideo.src = blobUrl;
            });

            // 设置canvas尺寸
            const width = widthInput.value ? parseInt(widthInput.value) : tempVideo.videoWidth;
            const height = Math.round(tempVideo.videoHeight * (width / tempVideo.videoWidth));
            canvas.width = width;
            canvas.height = height;

            // 创建GIF编码器
            const gif = new GIF({
                workers: 2,
                quality: parseInt(qualitySlider.value),
                width: width,
                height: height
            });

            // 转换参数
            const fps = parseInt(fpsSlider.value);
            const maxFrames = parseInt(maxFramesInput.value);
            const frameInterval = 1000 / fps;
            const duration = tempVideo.duration;
            const frameCount = Math.min(maxFrames, Math.floor(duration * fps));

            // 逐帧处理
            tempVideo.currentTime = 0;
            for (let i = 0; i < frameCount; i++) {
                tempVideo.currentTime = (i / frameCount) * duration;
                await new Promise(resolve => {
                    tempVideo.onseeked = () => {
                        ctx.drawImage(tempVideo, 0, 0, width, height);
                        gif.addFrame(ctx, { copy: true, delay: frameInterval });
                        
                        // 更新进度
                        const progress = ((i + 1) / frameCount) * 100;
                        progressBar.style.width = `${progress}%`;
                        statusText.textContent = `处理帧: ${i + 1}/${frameCount}`;
                        
                        resolve();
                    };
                });
            }

            // 渲染GIF
            statusText.textContent = '正在生成GIF...';
            await new Promise(resolve => {
                gif.on('finished', function(blob) {
                    const url = URL.createObjectURL(blob);
                    const a = document.createElement('a');
                    a.href = url;
                    a.download = `converted-${Date.now()}.gif`;
                    a.click();
                    URL.revokeObjectURL(url);
                    URL.revokeObjectURL(blobUrl);
                    resolve();
                });
                gif.render();
            });

        } catch (error) {
            console.error('转换失败:', error);
            throw error;
        }
    }

    // 事件监听
    const toggleBtn = document.querySelector('.gif-converter-toggle');
    const panel = document.querySelector('.gif-converter-panel');
    const convertBtn = document.getElementById('gifConverterConvertBtn');
    const videoList = document.getElementById('videoList');
    const qualitySlider = document.getElementById('gifConverterQuality');
    const fpsSlider = document.getElementById('gifConverterFps');
    const progressBar = panel.querySelector('.progress');
    const progressContainer = panel.querySelector('.progress-container');
    const statusText = panel.querySelector('.status');

    toggleBtn.addEventListener('click', () => {
        panel.classList.toggle('active');
        if (panel.classList.contains('active')) {
            updateVideoList();
        }
    });

    convertBtn.addEventListener('click', async () => {
        if (!selectedVideoUrl || !selectedVideoElement) return;

        try {
            convertBtn.disabled = true;
            progressContainer.style.display = 'block';
            await convertToGif(selectedVideoElement, selectedVideoUrl);
            
            // 重置状态
            convertBtn.disabled = false;
            progressContainer.style.display = 'none';
            statusText.textContent = '转换完成!';
            setTimeout(() => {
                progressBar.style.width = '0%';
            }, 1000);
        } catch (error) {
            convertBtn.disabled = false;
            statusText.textContent = '转换失败，请重试';
            console.error(error);
        }
    });

    // 显示当前设置值
    qualitySlider.addEventListener('input', () => {
        document.getElementById('gifConverterQualityValue').textContent = qualitySlider.value;
    });

    fpsSlider.addEventListener('input', () => {
        document.getElementById('gifConverterFpsValue').textContent = fpsSlider.value;
    });

    // 监听页面变化
    const observer = new MutationObserver(() => {
        if (panel.classList.contains('active')) {
            updateVideoList();
        }
    });

    observer.observe(document.body, {
        childList: true,
        subtree: true
    });
})();